﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BleSolution;
using System.Windows.Forms;
using Newtonsoft.Json;
using Windows.Data.Json;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using static YH.Bluetooth.WebSocketServer2;

namespace YH.Bluetooth
{

    public interface IWebSocketServerService
    {
        Task StartAsync();
        void Stop();
         Task SendMessageToAllAsync(string message);

        event DeviceFindeChangedEvent DeviceFindChanged;

    }

    public class WebSocketServer2 : IWebSocketServerService
    {
        private const int Port = 8080;
        private static HttpListener _httpListener;
        private static CancellationTokenSource _cts;
        private static ConcurrentDictionary<string, WebSocket> _clients = new ConcurrentDictionary<string, WebSocket>();


        /// <summary>
        /// 定义搜索蓝牙设备委托
        /// </summary>
        public delegate void DeviceFindeChangedEvent(string message);

        /// <summary>
        /// 搜索蓝牙事件
        /// </summary>
        public event DeviceFindeChangedEvent DeviceFindChanged;


        public async Task StartAsync()
        {
            _cts = new CancellationTokenSource();
            _httpListener = new HttpListener();
            _httpListener.Prefixes.Add($"http://*:{Port}/");
            _httpListener.Start();
            Console.WriteLine("WebSocket 服务器启动，监听端口：" + Port);
            MessageBox.Show("WebSocket 服务器启动，监听端口：" + Port);
            LogHelper.WriteLog("WebSocket 服务器启动，监听端口：" + Port);
            
            while (!_cts.Token.IsCancellationRequested)
            {
                try
                {
                    var context = await _httpListener.GetContextAsync().ConfigureAwait(false);
                    if (context.Request.IsWebSocketRequest)
                    {
                        _ = ProcessRequest(context); // Fire and forget but with proper error handling
                    }
                    else
                    {
                        LogHelper.WriteLog("打开服务器失败。");
                        context.Response.StatusCode = 400;
                        context.Response.Close();
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog($"HTTP Listener 错误：{ex}");
                    Console.WriteLine($"HTTP Listener 错误：{ex}");
                }
            }

            _httpListener.Stop();
            Console.WriteLine("WebSocket 服务器已停止。");
            LogHelper.WriteLog("WebSocket 服务器已停止。");
        }

        public void Stop()
        {
            _cts?.Cancel();
            foreach (var client in _clients.Values)
            {
                if (client.State == WebSocketState.Open)
                {
                    client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", _cts.Token).Wait(_cts.Token);
                }
                client.Dispose();
            }
            _clients.Clear();
            _httpListener?.Stop();
            _cts?.Dispose();
            _httpListener?.Close();
        }

        public async Task SendMessageToAllAsync(string message)
        {
            try
            {
                byte[] buffer = Encoding.UTF8.GetBytes(message);

                foreach (var pair in _clients)
                {
                    var webSocket = pair.Value;
                    if (webSocket.State == WebSocketState.Open)
                    {
                        LogHelper.WriteLog("发送数据--》》" + pair.Key + "--》" + message);
                         await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, _cts.Token).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                LogHelper.WriteLog(ex);
            }
        }

        private async Task ProcessRequest(HttpListenerContext context)
        {
            WebSocketContext wsContext;
            try
            {
                wsContext = await context.AcceptWebSocketAsync(subProtocol: null).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                context.Response.StatusCode = 500;
                context.Response.Close();
                Console.WriteLine($"无法建立 WebSocket 连接：{ex}");
                return;
            }

            var webSocket = wsContext.WebSocket;
            string id = Guid.NewGuid().ToString();
            _clients.TryAdd(id, webSocket);
            Console.WriteLine($"新连接 {id} 已添加到客户端列表");
            LogHelper.WriteLog($"新连接 {id} 已添加到客户端列表");

            byte[] buffer = new byte[1024 * 4]; // Increase buffer size to handle larger messages

            try
            {
                while (webSocket.State == WebSocketState.Open && !_cts.Token.IsCancellationRequested)
                {
                    var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cts.Token).ConfigureAwait(false);
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        string receivedMessage = Encoding.UTF8.GetString(buffer, 0, result.Count);
                        Console.WriteLine($"收到消息 [{id}]: {receivedMessage}");
                        LogHelper.WriteLog($"收到消息 [{id}]: {receivedMessage}");
                        SendMsgDataClass my_obj = JsonConvert.DeserializeObject<SendMsgDataClass>(receivedMessage);
                        if (my_obj != null) 
                        {
                            if (my_obj.command == CommondCode.find_device.ToString())
                            {
                                //搜索设备命令
                                this.DeviceFindChanged(receivedMessage);
                            }
                            else if (my_obj.command == CommondCode.connect_device.ToString())
                            {
                                //连接设备命令   

                            }
                            else if (my_obj.command == CommondCode.send_data.ToString())
                            {
                                //发送数据命令

                            }
                            else 
                            {
                                // 未知命令
                            }
                        }
                        // Echo the message back to the client
                        //await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), WebSocketMessageType.Text, result.EndOfMessage, _cts.Token).ConfigureAwait(false);
                    }
                    else if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, _cts.Token).ConfigureAwait(false);
                        break;
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("操作被取消。");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"WebSocket 连接异常：{ex}");
                if (webSocket.State == WebSocketState.Open)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "内部服务器错误", _cts.Token).ConfigureAwait(false);
                }
            }
            finally
            {
                _clients.TryRemove(id, out _);
                webSocket.Dispose();
                Console.WriteLine($"连接 {id} 已移除");
            }
        }
    }
}
